/* components */
import { 
  ConnectorModuleCreateConnectorNameDialog, 
  ConnectorModuleCreateConnectorDetailDialog 
} from '@src/modules/connector/components'
/* hooks */
import { 
  useConnectorCardSettingFetchModuleList, 
  useConnectorCardSettingFetchSaveConnectorOptions,
  useConnectorCardSettingCheckConnector 
} from '@src/modules/connector/hooks'
/* model */
import {
  ConnectorDialogDefaultDetailValue, 
  ConnectorDialogDetailData, 
  ConnectorModuleComponentNameEnum, 
  CreateConnectorDialogFieldNameEnum, 
  CreateConnectorModalFields,
} from '@src/modules/connector/model'
import Field from '@model/entity/Field'
/* scss */
import '@src/modules/connector/components/create-connector-dialog/index.scss'
/* vue */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { ComponentInstance, ComponentRenderProxy, computed, defineComponent, PropType, Ref, ref, CreateElement } from 'vue'
import { CommonComponentInstance } from '@model/VC'
/* util */
import Log from '@src/util/log'
import { isEmpty, isFalse } from '@src/util/type'
import { 
  connectComponentValueToServerValue, 
  connectorSaveValidate, 
  connectorAppModuleToFormCascaderDataSource 
} from '@src/modules/connector/util'
/* types */
import { 
  ConnectorGetModuleListParams, 
  ConnectorSaveOptionsParams 
} from '@src/modules/connector/types'
import { t } from '@src/locales'

export type ConnectorModuleCreateConnectorDialogProps = {
  // 业务类型 id
  bizTypeId: string;
  toBizType: string;
  fromBizType: string;
  title: string;
  // 显示隐藏状态
  visible: boolean;
  value: ConnectorDialogDetailData;
  isFetchModuleUseToBizType: boolean;
  fromBizTypeName: string;
  
}

export interface ConnectorModuleCreateConnectorDialogSetupState {
  
}

export enum ConnectorModuleCreateConnectorDialogEmitEventNameEnum {
  Input = 'input',
  Close = 'close',
  Finish = 'finish',
  Prev = 'prev',
  Next = 'next',
}

export type ConnectorModuleCreateConnectorDialogInstance = ComponentInstance & ConnectorModuleCreateConnectorDialogSetupState
export type ConnectorModuleCreateConnectorDialogVM = ComponentRenderProxy<ConnectorModuleCreateConnectorDialogProps> & CommonComponentInstance & ConnectorModuleCreateConnectorDialogInstance

export default defineComponent({
  name: ConnectorModuleComponentNameEnum.ConnectorModuleCreateConnectorDialog,
  emits: [
    ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Input,
    ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Close,
    ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Finish,
    ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Prev,
    ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Next,
  ],
  props: {
    bizTypeId: {
      type: String as PropType<string>,
      default: '',
    },
    toBizType: {
      type: String as PropType<string>,
      default: '',
    },
    fromBizType: {
      type: String as PropType<string>,
      default: '',
    },
    title: {
      type: String as PropType<string>,
      default: t('common.base.addModule', {module: t('common.connector.title.connector')}),
    },
    visible: {
      type: Boolean as PropType<boolean>,
      default: false,
    },
    value: {
      type: Object as PropType<ConnectorDialogDetailData>,
      default: () => ({}),
    },
    isFetchModuleUseToBizType: {
      type: Boolean as PropType<boolean>,
      default: true,
    },
    fromBizTypeName: {
      type: String as PropType<string>,
      default: ''
    },
    isShowSelectLanguage: {
      type: Boolean as PropType<boolean>,
      default: false,
    },
    bizActionCode: {
      type: String as PropType<string>,
      default: '',
    },
    currentNodeId: {
      type: String as PropType<string>,
      default: '',
    }
  },
  data() {
    return {
      fields: CreateConnectorModalFields.slice(),
    }
  },
  setup(props: ConnectorModuleCreateConnectorDialogProps, { emit }) {
    
    // paas 关联应用
    const { loading: fetchModuleListLoading, moduleList, fetchModuleList } = useConnectorCardSettingFetchModuleList()
    
    // 检查连接器是否已经被创建
    const { loading: fetchCheckConnectorLoading, checkConnector } = useConnectorCardSettingCheckConnector()
    
    // 保存连接器配置
    const { loading: fetchSaveConnectorOptionsLoading, fetchSaveConnectorOptions } = useConnectorCardSettingFetchSaveConnectorOptions()
    
    // 是否切换了PaaS应用
    const isPaasAppChange = ref(false)
    
    // 是否显示 新建连接器附加组件 详情弹窗 (默认不显示)
    const isShowCreateConnectorDetailDialog = ref(false)
    
    // 是否显示 新建连接器附加组件 名称弹窗
    const isShowCreateConnectorNameDialog = computed(() => props.visible)
    
    const nameFormValue: Ref<Record<CreateConnectorDialogFieldNameEnum, string | string[]>> = ref({
      [CreateConnectorDialogFieldNameEnum.RelationAppForm]: [''],
      [CreateConnectorDialogFieldNameEnum.Name]: '',
      [CreateConnectorDialogFieldNameEnum.Description]: ''
    })
    
    const detailValue: Ref<ConnectorDialogDetailData> = ref(ConnectorDialogDefaultDetailValue)
    
    const onNameDialogCloseHandler = () => {
      nameFormValue.value = {
        [CreateConnectorDialogFieldNameEnum.RelationAppForm]: [''],
        [CreateConnectorDialogFieldNameEnum.Name]: '',
        [CreateConnectorDialogFieldNameEnum.Description]: ''
      }
      emit(ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Close)
    }
    
    const onCreateConnectorDetailDialogCloseHandler = () => {
      initConnectorDialogDefaultDetailValue()
      emit(ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Close)
    }
    
    const onCreateConnectorDetailDialogFinishHandler = () => {
      emit(ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Finish)
    }
    
    const onDialogPrevHandler = () => {
      emit(ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Prev)
    }
    
    const onDialogNextHandler = () => {
      emit(ConnectorModuleCreateConnectorDialogEmitEventNameEnum.Next)
    }
    
    // 初始化detailValue
    const initConnectorDialogDefaultDetailValue = () => {
      detailValue.value = ConnectorDialogDefaultDetailValue
    }
    
    return {
      isPaasAppChange,
      isShowCreateConnectorDetailDialog,
      isShowCreateConnectorNameDialog,
      
      nameFormValue,
      detailValue,
      
      fetchCheckConnectorLoading,
      fetchModuleListLoading,
      fetchSaveConnectorOptionsLoading,
      
      moduleList,
      
      checkConnector,
      fetchModuleList,
      fetchSaveConnectorOptions,
      
      onNameDialogCloseHandler,
      onCreateConnectorDetailDialogCloseHandler,
      onCreateConnectorDetailDialogFinishHandler,
      onDialogPrevHandler,
      onDialogNextHandler,
      initConnectorDialogDefaultDetailValue
    }
    
  },
  watch: {
    visible: {
      handler(newValue) {
        if (newValue) {
          this.initialize()
        }
      },
      immediate: true
    }
  },
  methods: {
    /** 
     * @description 保存连接器配置实现
    */
    fetchSaveConnectorOptionsImpl(params: ConnectorSaveOptionsParams) {
      
      this.fetchSaveConnectorOptions(params)
        .then(() => {
          // 关闭弹框 更新列表数据
          this.initConnectorDialogDefaultDetailValue()
          this.hideCreateConnectorDetailDialog()
          this.onNameDialogCloseHandler()
          
          this.onCreateConnectorDetailDialogFinishHandler()
          
        })
        .catch(error => {
          Log.error(error, this.fetchSaveConnectorOptions.name)
        })
      
    },
    /**
    * @description 获取属性列表
    * @return {Record<string, any>} 属性列表
    */  
    getAttributes(): Record<string, any> {
      return {
        on: {
          'closed': () => {
            this.onNameDialogCloseHandler()
          }
        }
      }
    },
    /** 
     * @description 获取 当前选中的 paas 应用 id
    */
    getSelectPaasAppId() {
      
      const relationAppFormValue = this.nameFormValue[CreateConnectorDialogFieldNameEnum.RelationAppForm]
      const selectPaasAppId = relationAppFormValue[relationAppFormValue.length - 1]
      
      return selectPaasAppId
    },
    /**
     * @description 隐藏 新建连接器附加组件 详情弹窗
    */
    hideCreateConnectorDetailDialog() {
      this.isShowCreateConnectorDetailDialog = false
    },
    /** 
     * @description 初始化
    */
    initialize() {
      
      const params: ConnectorGetModuleListParams = { 
        fromBizTypeId: this.bizTypeId, 
      }
      
      if (this.isFetchModuleUseToBizType) {
        // 后端让先不传toBizType
        // params.toBizType = this.toBizType
      }
      
      if (isEmpty(this.bizTypeId) && isEmpty(this.toBizType)) {
        Log.warn('[create-connector-dialog] bizTypeId or toBizType is empty', this.initialize.name)
        return
      }
      
      this.fetchModuleList(params).then(result => {
        
        const dataSource = connectorAppModuleToFormCascaderDataSource(result)
        
        try {
          
          this.fields[0].setting!.dataSource = dataSource
          
        } catch (error) {
          
          Log.error(error, this.initialize.name)
          
        }
        
      })
    },
    /** 
     * @description 名称表单输入事件
    */
    onNameFormInputHandler(field: Field, value: string | string[]) {
      
      const { fieldName } = field
      
      if(fieldName === CreateConnectorDialogFieldNameEnum.RelationAppForm) {
        this.nameFormValue[fieldName] = value 
        // this.nameFormValue['name'] = value[1]
      } else {
        // @ts-ignore
        this.nameFormValue[fieldName] = value
      }
      
    },
    /** 
     * @description 名称表单提交 下一步
    */
    onNameDialogNextHandler(selectValue: Record<string, any>) {
      // 初始化detailValue
      this.initConnectorDialogDefaultDetailValue()
      // 之前选择的paas应用Id
      const originPaasAppId = this.detailValue.paasApp.id
      // 当前选择的paas应用Id
      const selectPaasAppId = this.getSelectPaasAppId()
      // const paasApp = getToFormFromModuleListById(this.moduleList, selectPaasAppId)
      
      this.detailValue.bizTypeId = this.bizTypeId
      this.detailValue.appType = selectValue.appType
      // 给连接器附加组件赋值
      // this.detailValue.paasApp = paasApp
      this.genResetPaasAppValue(selectValue)
      // 是否切换了paas应用
      this.isPaasAppChange = originPaasAppId !== selectPaasAppId
      
      Log.info(this.detailValue, 'next detailValue', this.onNameDialogNextHandler.name)
      
      this.onDialogNextHandler()
      this.showCreateConnectorDetailDialog()
    },

    /**
     * 获取当前选选择的第三方连接应用的数据---（现在所有的选择后都赋值在paasApp ,不想改对应的paasApp key(涉及好几个地方)）
     * @param selectAppVal 
     */
    genResetPaasAppValue(selectAppVal: Record<string, any>) {
      const { bizTypeId, label: name, icon, bizType } = selectAppVal
      this.detailValue.paasApp = {
        id: bizTypeId,
        name,
        icon,
        type: bizType,
      }
    },

    /**
     * @description 检查连接器是否已经被创建 
     */
    checkCreateConnector(fetchParam: Record<string, any>) {
      // 当前选择的paas应用Id
      // const selectPaasAppId = this.getSelectPaasAppId()
      // const paasApp = getToFormFromModuleListById(this.moduleList, selectPaasAppId)
      
      this.detailValue.bizTypeId = this.bizTypeId
      
      // 给连接器附加组件赋值---这里赋值因为后续不想改paasApp中取值所以直接赋值
      this.genResetPaasAppValue(fetchParam)

      return new Promise((resolve, reject) => {
        const { id, type } = this.detailValue.paasApp
        const params = {
          fromBizType: this.fromBizType,
          fromBizTypeId: this.bizTypeId,
          toBizTypeId: id,
          toBizType: type,
        }
        // @ts-ignore
        resolve(this.checkConnector(params))
      })
    },
    /** 
     * @description 连接器附件组件 详情 弹窗 上一步
    */
    onDetailDialogPrevHandler() {
      this.onDialogPrevHandler()
      this.hideCreateConnectorDetailDialog()
    },
    onValueInputHandler(value: ConnectorDialogDetailData) {
      this.detailValue = value
    },
    onDetailDialogNextHandler(detailValue: ConnectorDialogDetailData) {
      
      Log.info(detailValue, 'detailValue', this.onDetailDialogNextHandler.name)
      Log.info(this.nameFormValue, 'nameFormValue', this.onDetailDialogNextHandler.name)
      
      const validated = connectorSaveValidate(detailValue)
      
      if (isFalse(validated)) {
        
        Log.warn('validate fail', connectorSaveValidate.name)
        
        return
        
      }
      
      const params = connectComponentValueToServerValue(
        this.nameFormValue,
        detailValue,
        this.bizTypeId,
        this.fromBizType,
        detailValue.paasApp.type
      )
      
      Log.info(params, 'params', this.onDetailDialogNextHandler.name)
      
      this.fetchSaveConnectorOptionsImpl(params)
      
    },
    /**
     * @description 显示 新建连接器附加组件 详情弹窗
    */
    showCreateConnectorDetailDialog() {
      this.isShowCreateConnectorDetailDialog = true
    }
  },
  render(h: CreateElement) {
    
    const attrs = this.getAttributes()
    
    return (
      <div class={ConnectorModuleComponentNameEnum.ConnectorModuleCreateConnectorDialog} {...attrs}>
        
        <ConnectorModuleCreateConnectorNameDialog 
          checkCreateConnector={this.checkCreateConnector}
          isShowSelectLanguage={this.isShowSelectLanguage}
          title={this.title}
          disabled={this.fetchModuleListLoading}
          nextDisabled={this.fetchCheckConnectorLoading}
          visible={this.isShowCreateConnectorNameDialog}
          fields={this.fields}
          value={this.nameFormValue}
          onInput={this.onNameFormInputHandler}
          onNext={this.onNameDialogNextHandler}
          onClose={this.onNameDialogCloseHandler}
        />
        
        <ConnectorModuleCreateConnectorDetailDialog
          title={this.title}
          finishDisabled={this.fetchSaveConnectorOptionsLoading}
          visible={this.isShowCreateConnectorDetailDialog}
          isPaasAppChange={this.isPaasAppChange}
          value={this.detailValue}
          bizTypeId={this.bizTypeId}
          fromBizType={this.fromBizType}
          fromBizTypeName={this.fromBizTypeName}
          toBizType={this.toBizType}
          bizActionCode={this.bizActionCode}
          currentNodeId={this.currentNodeId}
          onPrev={this.onDetailDialogPrevHandler}
          onNext={this.onDetailDialogNextHandler}
          onInput={this.onValueInputHandler}
        />
        
      </div>
    )
  }
})
